package com.easyedu.core.exceptionhandler;


import com.easyedu.core.entity.BaseError;
import com.easyedu.core.exception.EasyEduException;
import com.easyedu.core.util.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;
import java.util.List;

/**
 * @author   linxi
 * @date     2022/3/20
 * @describe 全局异常处理
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    /**
     * 空指针异常
     **/
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public R error(Exception e) {
        e.printStackTrace();
        return R.error().message("发生了空指针异常！");
    }

    /**
     * 功能描述: 参数校验异常处理
     *
     * @param exception 1
     * @return : com.easyedu.common.util.R
     **/
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public R validationBodyException(MethodArgumentNotValidException exception) {
        BindingResult result = exception.getBindingResult();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p -> {
                FieldError fieldError = (FieldError) p;
                LOGGER.warn("Data check failure : object={}, field={}, errorMessage={}", fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
            });
            ObjectError objectError = errors.get(0);
            String errMsg = objectError == null ? "请求参数错误" : objectError.getDefaultMessage();
            return R.error(BaseError.ERR_PARA.getCode()).message(errMsg);
        }
        //其他错误
        return R.error().message("请求参数错误");
    }

    /**
     * 功能描述: 参数校验异常处理</br>
     * 处理list验证时起作用
     *
     * @param exception 1
     * @return : com.easyedu.common.util.R
     **/
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public R validationListParamException(ConstraintViolationException exception) {
        String errMsg = exception.getMessage();
        LOGGER.warn(errMsg);
        return R.error(BaseError.ERR_PARA.getCode()).message(errMsg);

    }

    /**
     * 自定义异常
     **/
    @ExceptionHandler(EasyEduException.class)
    @ResponseBody
    public R error(EasyEduException e) {
        LOGGER.warn("EasyEduException:" + " code:" + e.getCode() + " msg:" + e.getMsg());
        return R.error().code(e.getCode()).message(e.getMsg());
    }
}
